<template>
	<view class="page-container">
		<!-- 筛选区域 -->
		<view class="tech-card filter-section">
			<view class="card-title">
				<view class="title-icon">🎯</view>
				<text>Banner 管理</text>
			</view>

			<view class="filter-content">
				<view class="filter-left">
					<el-button @click="addBanner" class="tech-button primary-button">
						<text>➕ 新增 Banner</text>
					</el-button>
					<view class="drag-tip">
						<text>💡 提示：可拖拽表格行进行排序</text>
					</view>
				</view>
			</view>
		</view>

		<!-- 数据表格区域 -->
		<view class="tech-card table-section">
			<view class="card-title">
				<view class="title-icon">📊</view>
				<text>Banner 列表</text>
				<text class="file-count" v-if="bannerList.length > 0">共 {{ bannerList.length }} 个 Banner</text>
			</view>

			<el-table
				ref="dragTable"
				:data="bannerList"
				v-loading="loading"
				class="tech-table"
				size="small"
				:header-cell-style="{ background: '#1a1f3a', color: '#00f0ff', fontWeight: 'bold' }"
				height="calc(100vh - 280px)"
				row-key="objectId">

				<el-table-column type="index" label="#" width="80" align="center">
					<template slot-scope="scope">
						<view class="index-with-drag">
							<span class="drag-handle">⋮⋮</span>
							<span>{{ scope.$index + 1 }}</span>
						</view>
					</template>
				</el-table-column>

				<el-table-column prop="image" label="Banner 图片" width="250" align="center">
					<template slot-scope="scope">
						<el-image
							v-if="scope.row.image"
							class="banner-image"
							:src="scope.row.image"
							:preview-src-list="[scope.row.image]"
							fit="cover"
						/>
						<view v-else class="no-image-text">暂无图片</view>
					</template>
				</el-table-column>

				<el-table-column prop="title" label="Banner 标题" min-width="150" show-overflow-tooltip />

				<el-table-column label="显示状态" width="100" align="center">
					<template slot-scope="scope">
						<el-switch
							v-model="scope.row.isShow"
							@change="toggleShowStatus(scope.row)"
							active-color="#00f0ff"
							inactive-color="#4a5568"
							class="status-switch"
						></el-switch>
					</template>
				</el-table-column>

				<el-table-column prop="createdAt" label="创建日期" width="160" align="center" />

				<el-table-column fixed="right" label="操作" width="150" align="center">
					<template slot-scope="scope">
						<el-button type="text" class="action-button" @click="editThis(scope.row)">
							编辑
						</el-button>
						<el-button type="text" class="action-button delete-button" @click="deleteThis(scope.row)">
							删除
						</el-button>
					</template>
				</el-table-column>
			</el-table>
		</view>

		<!-- Banner 编辑弹窗 -->
		<el-dialog
			:title="bannerParams.objectId ? '编辑 Banner' : '新增 Banner'"
			:visible.sync="bannerShow"
			:width="dialogWidth"
			:close-on-click-modal="false"
			class="tech-dialog">

			<view class="dialog-content">
				<!-- 图片上传区域 -->
				<view class="upload-section">
					<view class="section-label">Banner 图片 (3:2 比例)</view>
					<view v-if="bannerParams.image" class="image-preview">
						<el-image class="preview-img" :src="bannerParams.image" fit="cover" />
						<view class="image-actions">
							<el-button @click="select" class="tech-button" size="small">重新上传</el-button>
							<el-button @click="bannerParams.image = ''" class="tech-button cancel-button" size="small">删除</el-button>
						</view>
					</view>
					<view v-else class="upload-placeholder" @click="select">
						<i class="el-icon-upload"></i>
						<text>点击上传 Banner 图片</text>
					</view>
				</view>

				<!-- 表单 -->
				<el-form
					label-width="90px"
					:model="bannerParams"
					ref="bannerForm"
					size="small"
					class="tech-form">

					<el-form-item label="标题">
						<el-input
							v-model="bannerParams.title"
							placeholder="请输入 Banner 标题"
							maxlength="50"
							show-word-limit
							class="tech-input"
						></el-input>
					</el-form-item>

					<el-form-item label="关联文件">
						<el-input
							v-model="bannerParams.title"
							placeholder="点击选择关联文件"
							@click.native="dialogShow = true, getArtpptData()"
							readonly
							class="tech-input"
						>
							<i slot="suffix" class="el-icon-search"></i>
						</el-input>
					</el-form-item>

					<el-form-item label="显示状态">
						<el-switch
							v-model="bannerParams.isShow"
							active-text="显示"
							inactive-text="隐藏"
							active-color="#00f0ff"
							inactive-color="#4a5568"
							class="tech-switch"
						></el-switch>
					</el-form-item>
				</el-form>
			</view>

			<span slot="footer" class="dialog-footer">
				<el-button @click="bannerShow = false" class="tech-button cancel-button">取 消</el-button>
				<el-button @click="confirmAdd" :loading="saveLoading" class="tech-button primary-button">
					{{ saveLoading ? '保存中...' : '确 定' }}
				</el-button>
			</span>
		</el-dialog>

		<!-- 选择文件弹窗 -->
		<el-dialog
			title="选择关联文件"
			:visible.sync="dialogShow"
			width="90%"
			:close-on-click-modal="false"
			class="tech-dialog select-file-dialog">

			<view class="dialog-search">
				<el-input
					placeholder="请输入搜索关键词"
					v-model="params.searchText"
					@change="getArtpptData"
					class="tech-input"
					clearable
				>
					<i slot="prefix" class="el-icon-search"></i>
				</el-input>
			</view>

			<el-table
				:data="artpptList"
				class="tech-table"
				size="small"
				:header-cell-style="{ background: '#1a1f3a', color: '#00f0ff', fontWeight: 'bold' }"
				height="calc(70vh - 180px)">

				<el-table-column type="index" label="#" width="60" align="center" />
				<el-table-column prop="number" label="编号" width="120" show-overflow-tooltip />
				<el-table-column prop="title" label="标题" min-width="150" show-overflow-tooltip />
				<el-table-column prop="classDesc" label="分类" width="120" />
				<el-table-column prop="age" label="年龄" width="80" align="center" />
				<el-table-column prop="price" label="价格" width="80" align="center">
					<template slot-scope="scope">
						<view class="price-tag">¥{{ scope.row.price }}</view>
					</template>
				</el-table-column>
				<el-table-column prop="images" label="图片" width="80" align="center">
					<template slot-scope="scope">
						<el-image
							v-if="scope.row.images && scope.row.images.length"
							class="preview-image-small"
							:src="scope.row.images[0]"
							fit="cover"
						/>
					</template>
				</el-table-column>
				<el-table-column fixed="right" label="操作" width="100" align="center">
					<template slot-scope="scope">
						<el-button
							type="text"
							class="action-button"
							@click="selectFile(scope.row)">
							选择
						</el-button>
					</template>
				</el-table-column>
			</el-table>

			<view class="pagination-wrapper">
				<el-pagination
					@current-change="handleCurrentChange"
					@size-change="handleSizeChange"
					:current-page="params.pageNum"
					:page-sizes="[20, 40, 60, 80, 100]"
					:page-size="params.pageSize"
					:total="maxCount"
					layout="total, sizes, prev, pager, next, jumper"
					background>
				</el-pagination>
			</view>
		</el-dialog>

		<!-- 图片裁剪弹窗 -->
		<el-dialog
			title="图片裁剪"
			:visible.sync="bannerShow1"
			width="800px"
			:close-on-click-modal="false"
			class="tech-dialog cropper-dialog">

			<vueCropper
				ref="cropper"
				:img="bannerParams.image"
				:outputSize="1"
				outputType="png"
				:fixed="true"
				:autoCrop="true"
				:centerBox="true"
				:fixedNumber="[3,2]"
				class="cropper-content"
			/>

			<span slot="footer" class="dialog-footer">
				<el-button @click="bannerShow1 = false" class="tech-button cancel-button">取 消</el-button>
				<el-button @click="getcropImage" :loading="uploadLoading" class="tech-button primary-button">
					{{ uploadLoading ? '上传中...' : '确 定' }}
				</el-button>
			</span>
		</el-dialog>
	</view>
</template>

<script>
	import Sortable from 'sortablejs'
	import UUID from 'uuid';
	import {
		VueCropper
	} from 'vue-cropper'
	import uploadFile from '@/js_sdk/tencentcloud/upload-file.js';
	import getFileAccessUrl from '@/js_sdk/tencentcloud/getFileAccessUrl';

	let that
	export default {
		components: {
			VueCropper
		},
		data() {
			return {
				dialogShow: false,
				bannerShow: false,
				bannerShow1: false,
				loading: false,
				saveLoading: false,
				uploadLoading: false,

				chooseItem: '',
				artpptList: [],
				bannerList: [],
				maxCount: 1,
				maxPage: 1,
				sortable: null,

				bannerParams: {
					image: '',
					artpptId: '',
					title: '',
					isShow: true,
				},

				params: {
					pageSize: 20,
					pageNum: 1,
					typeDesc: '',
					searchText: '',
				}
			}
		},

		computed: {
			// 响应式弹窗宽度
			dialogWidth() {
				if (typeof window !== 'undefined') {
					const width = window.innerWidth
					if (width < 768) return '90%'
					if (width < 1200) return '60%'
					return '50%'
				}
				return '50%'
			}
		},

		onLoad() {
			that = this
			that.getData()
		},

		mounted() {
			that = this
			this.$nextTick(() => {
				this.initSortable()
			})
		},

		beforeDestroy() {
			if (this.sortable) {
				this.sortable.destroy()
			}
		},

		methods: {
			// 初始化拖拽排序
			initSortable() {
				const el = this.$refs.dragTable?.$el?.querySelector('.el-table__body-wrapper tbody')
				if (!el) return

				this.sortable = Sortable.create(el, {
					animation: 150,
					handle: '.el-table__row',
					ghostClass: 'sortable-ghost',
					chosenClass: 'sortable-chosen',
					dragClass: 'sortable-drag',
					onEnd: (evt) => {
						const { oldIndex, newIndex } = evt
						if (oldIndex === newIndex) return

						const oldItem = this.bannerList[oldIndex]
						const newItem = this.bannerList[newIndex]

						const movedItem = this.bannerList.splice(oldIndex, 1)[0]
						this.bannerList.splice(newIndex, 0, movedItem)

						this.saveDragOrder(oldItem.objectId, newItem.objectId)
					}
				})
			},

			// 保存拖拽排序
			saveDragOrder(objectId1, objectId2) {
				this.$message({
					message: '正在保存排序...',
					type: 'info',
					duration: 1000
				})

				// 调用换位接口
				this.$http.Post("admin/banner/changeOrder", {
					objectId1: objectId1,
					objectId2: objectId2,
				}, "").then(res => {
					this.$message({
						message: '排序保存成功',
						type: 'success',
						duration: 1500
					})
				}).catch(err => {
					// 失败时恢复原顺序
					this.$message({
						message: '排序保存失败',
						type: 'error'
					})
					this.getData()
				})
			},

			// 切换显示状态
			toggleShowStatus(row) {
				this.$http.Post("admin/banner/save", {
					objectId: row.objectId,
					image: row.image,
					title: row.title,
					artpptId: row.artpptId,
					isShow: row.isShow
				}, "").then(res => {
					this.$message({
						message: row.isShow ? 'Banner 已显示' : 'Banner 已隐藏',
						type: 'success',
						duration: 1500
					})
				}).catch(err => {
					// 失败时恢复原状态
					row.isShow = !row.isShow
					this.$message({
						message: '状态切换失败',
						type: 'error'
					})
				})
			},

			// 选择文件
			selectFile(row) {
				this.bannerParams.artpptId = row.objectId
				this.bannerParams.title = row.title
				this.dialogShow = false
			},

			// 分页大小改变
			handleSizeChange(value) {
				this.params.pageSize = value
				this.params.pageNum = 1
				this.getArtpptData()
			},

			select() {
				uni.chooseImage({
					count: 1,
					success: (rst) => {
						// 设置url的值，显示控件
						this.bannerParams.image = rst.tempFilePaths[0];
						this.bannerShow1 = true
					}
				});
			},

			getcropImage() {
				this.uploadLoading = true
				this.$refs.cropper.getCropBlob(async data => {
					// do something
					this.useQiniiyun_upload([this.cblobToFile(data, new Date().getTime() + ".png")]); // 这个是调用七牛云上传
				})
			},
			
			
			async useQiniiyun_upload(files) {
				console.log(files)
				let that = this
			
				let promises = []
				for (let file of files) {
					let promise = new Promise(function(resolve, reject) {
			
						let filePath = undefined;
						let fileExt;
						if (typeof file === 'string') {
							filePath = file;
							file = undefined;
							fileExt = filePath.split('?')[0].split('.').pop();
						} else {
							fileExt = file.name.split('.').pop();
						}
						// 支付宝小程序上传文件API必传fileType
						// 通过支付宝小程序环境下选择文件的时候，通过返回的filePath取得的扩展名可能是image/video/audio
						let fileType = undefined;
						// ifdef MP-ALIPAY
						if (fileExt === 'image') {
							fileExt = 'jpg';
						} else if (fileExt === 'video') {
							fileExt = 'mp4';
						} else if (fileExt === 'audio') {
							fileExt = 'mp3';
						} else if (fileExt === 'zip') {
							fileExt = 'zip';
						}
						fileType = that.getMediaType(fileExt);
						let fileName = `${UUID.v1()}.${fileExt}`;
						/**
						 * 参数：
						 * 1.file：要上传的文件选择器或者文件对象
						 *2. filename_qn：上传到七牛后保存的文件名。如果不指定，则由七牛服务器自动生成。
						 *3. token：上传凭证，详见 上传策略
						 */
						// 上传以后的文件名-存在七牛云的文件名字-空间的域名+文件名就可以访问文件了！最好做时间戳+随机数这样做一个唯一的文件名字
						const filename_qn = that.common.getDay(0) + "/brand/" + fileName;
						// console.log('上传前生成的文件名字：', filename_qn)
						// 发起请求,获取上传文件需要的uploadToken
						uni.request({
							url: 'https://fc-mp-d19b9f62-6e96-422b-8eb6-44b08a354d76.next.bspapp.com/uploadQiNiu',
							method: 'POST',
							// data: {},
							success: (res) => {
								const token = res.data.uploadToken;
								// 获取成功后发起文件上传
								/**
								 * url:我这里是（https://upload-z2.qiniup.com）：华南-广东 对应的七牛云的地址-其他的可以自行百度
								 * filePath：文件本地临时地址，一次只能一个，字符串类型
								 */
								uni.uploadFile({
									url: 'https://upload-cn-east-2.qiniup.com',
									filePath: file.path,
									name: 'file',
									formData: {
										'key': filename_qn, // 存到七牛云后的文件名字，访问图片会用到
										'token': token, // uploadToken，需要动态获取，调用云函数接口获取
									},
									// 存成功后的回调
									success: (uploadFileRes) => {
										let key = JSON.parse(uploadFileRes.data).key;
										// 空间绑定的域名（在七牛云配置）+key就是文件的访问地址
										const img_url = 'https://qiniu.jimuzhou.cloud/' + key
										resolve(img_url)
									},
									fail: (err) => {
										console.log('上传失败了', err);
										uni.hideLoading();
									}
								});
							}
						})
					})
					promises.push(promise)
				}
				Promise.all(promises).then(function(res) {
					console.log(res)
					that.bannerParams.image = res[0]
					that.bannerShow1 = false
					that.uploadLoading = false
					that.$message({
						message: '图片上传成功',
						type: 'success'
					})
				}).catch(err => {
					that.uploadLoading = false
					that.$message({
						message: '图片上传失败',
						type: 'error'
					})
				});
			},
			
			getMediaType(ext) {
				if (/^(jpg|jpeg|png|gif|bmp|webp)$/.test(ext.toLowerCase())) {
					return 'image';
				}
				if (/^(mp4|mpeg|qsv|mov|avi|3gp)$/.test(ext.toLowerCase())) {
					return 'video';
				}
				if (/^(mp3|wma|wav|m4a)$/.test(ext.toLowerCase())) {
					return 'audio';
				}
				return 'other';
			},

			cblobToFile(blob, fileName) {
				return new window.File([blob], fileName, {
					type: blob.type
				})
			},

			addBanner() {
				that.resetForm()
				that.bannerShow = true
			},

			editThis(item) {
				that.bannerParams.image = item.image
				that.bannerParams.objectId = item.objectId
				that.bannerParams.artpptId = item.artpptId
				that.bannerParams.title = item.title
				that.bannerParams.isShow = item.isShow !== undefined ? item.isShow : true
				that.bannerShow = true
			},

			deleteThis(item) {
				that.$confirm(`确定要删除 Banner "${item.title}" 吗？`, '提示', {
					confirmButtonText: '确定',
					cancelButtonText: '取消',
					type: 'warning'
				}).then(() => {
					that.$http.Post("admin/banner/remove", {
						objectId: item.objectId
					}, "").then(res => {
						that.$message({
							message: '删除成功',
							type: 'success'
						})
						that.getData()
					}).catch(err => {
						that.$message({
							message: '删除失败',
							type: 'error'
						})
					})
				}).catch(() => {
					// 取消删除
				})
			},

			//添加banner
			confirmAdd() {
				if (!this.bannerParams.image) {
					this.$message({
						message: '请上传 Banner 图片',
						type: 'warning'
					})
					return
				}
				if (!this.bannerParams.title) {
					this.$message({
						message: '请输入 Banner 标题',
						type: 'warning'
					})
					return
				}

				this.saveLoading = true
				this.$http.Post("admin/banner/save", that.bannerParams, "").then(res => {
					that.$message({
						message: that.bannerParams.objectId ? '修改成功' : '添加成功',
						type: 'success'
					})
					that.bannerShow = false
					that.getData()
					that.resetForm()
				}).catch(err => {
					that.$message({
						message: '保存失败',
						type: 'error'
					})
				}).finally(() => {
					this.saveLoading = false
				})
			},

			// 重置表单
			resetForm() {
				this.bannerParams = {
					image: '',
					artpptId: '',
					title: '',
					isShow: true,
				}
			},

			handleCurrentChange(value) {
				that.params.pageNum = value
				that.getArtpptData()
			},

			getData() {
				this.loading = true
				this.$http.Post("admin/banner/list", {}, "").then(res => {
					// 确保每个 banner 都有 isShow 字段
					this.bannerList = (res.data || []).map(item => ({
						...item,
						isShow: item.isShow !== undefined ? item.isShow : true
					}))
					// 数据更新后重新初始化拖拽
					this.$nextTick(() => {
						if (this.sortable) {
							this.sortable.destroy()
						}
						this.initSortable()
					})
				}).catch(err => {
					this.$message({
						message: '获取数据失败',
						type: 'error'
					})
					this.bannerList = []
				}).finally(() => {
					this.loading = false
				})
			},

			getArtpptData() {
				this.$http.Post("admin/artPPT/list", that.params, "加载中...").then(res => {
					this.artpptList = res.data
					that.maxCount = res.maxCount
					that.maxPage = res.maxPage
				})
			}
		}
	}
</script>

<style scoped>
/* ==================== 全局容器 ==================== */
.page-container {
	min-height: 100vh;
	padding: 16px;
	background: linear-gradient(135deg, #0a0e27 0%, #1a1f3a 50%, #0f1729 100%);
	font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}

/* ==================== 科技卡片 ==================== */
.tech-card {
	background: rgba(26, 31, 58, 0.6);
	backdrop-filter: blur(10px);
	border-radius: 12px;
	padding: 16px;
	margin-bottom: 16px;
	border: 1px solid rgba(0, 240, 255, 0.2);
	box-shadow:
		0 8px 32px rgba(0, 240, 255, 0.1),
		inset 0 1px 0 rgba(255, 255, 255, 0.1);
	transition: all 0.3s ease;
	position: relative;
	overflow: hidden;
}

.tech-card::before {
	content: '';
	position: absolute;
	top: 0;
	left: -100%;
	width: 100%;
	height: 2px;
	background: linear-gradient(90deg, transparent, #00f0ff, transparent);
	animation: scan 3s infinite;
}

@keyframes scan {
	0%, 100% {
		left: -100%;
	}
	50% {
		left: 100%;
	}
}

.tech-card:hover {
	border-color: rgba(0, 240, 255, 0.4);
}

/* ==================== 卡片标题 ==================== */
.card-title {
	display: flex;
	align-items: center;
	font-size: 16px;
	font-weight: 600;
	color: #00f0ff;
	margin-bottom: 12px;
	padding-bottom: 8px;
	border-bottom: 1px solid rgba(0, 240, 255, 0.2);
	text-shadow: 0 0 10px rgba(0, 240, 255, 0.5);
}

.title-icon {
	margin-right: 6px;
	font-size: 18px;
	filter: drop-shadow(0 0 8px rgba(0, 240, 255, 0.6));
}

.file-count {
	margin-left: auto;
	font-size: 12px;
	color: #7f8ea3;
	font-weight: normal;
	background: rgba(0, 240, 255, 0.1);
	padding: 2px 10px;
	border-radius: 10px;
	border: 1px solid rgba(0, 240, 255, 0.2);
}

/* ==================== 筛选区域 ==================== */
.filter-content {
	display: flex;
	gap: 16px;
	align-items: center;
	justify-content: space-between;
}

.filter-left {
	display: flex;
	gap: 16px;
	align-items: center;
	flex: 1;
}

/* 拖拽提示 */
.drag-tip {
	display: flex;
	align-items: center;
	color: #7f8ea3;
	font-size: 12px;
	padding: 4px 12px;
	background: rgba(0, 240, 255, 0.05);
	border: 1px solid rgba(0, 240, 255, 0.2);
	border-radius: 6px;
	animation: pulse 2s ease-in-out infinite;
}

@keyframes pulse {
	0%, 100% {
		opacity: 0.7;
	}
	50% {
		opacity: 1;
	}
}

/* ==================== 科技按钮 ==================== */
.tech-button {
	padding: 8px 20px !important;
	border-radius: 6px !important;
	font-weight: 600 !important;
	font-size: 13px !important;
	letter-spacing: 0.3px;
	transition: all 0.3s ease !important;
	border: none !important;
	position: relative;
	overflow: hidden;
	height: 36px;
}

.primary-button {
	background: linear-gradient(135deg, #00f0ff 0%, #0099cc 100%) !important;
	color: #0a0e27 !important;
	box-shadow: 0 4px 15px rgba(0, 240, 255, 0.3);
}

.primary-button:hover {
	box-shadow: 0 6px 20px rgba(0, 240, 255, 0.5);
	transform: translateY(-2px);
}

.cancel-button {
	background: rgba(127, 142, 163, 0.2) !important;
	color: #b8c5d6 !important;
	border: 1px solid rgba(127, 142, 163, 0.3) !important;
}

.cancel-button:hover {
	background: rgba(127, 142, 163, 0.3) !important;
	border-color: rgba(127, 142, 163, 0.5) !important;
}

/* ==================== 表格区域 ==================== */
.table-section {
	height: calc(100vh - 200px);
	display: flex;
	flex-direction: column;
}

/* ==================== 表格样式 ==================== */
.tech-table {
	width: 100%;
	flex: 1;
}

.tech-table >>> .el-table {
	background: transparent !important;
	color: #e0e6ed;
}

.tech-table >>> .el-table::before {
	background: transparent !important;
}

.tech-table >>> .el-table th,
.tech-table >>> .el-table tr {
	background: transparent !important;
}

.tech-table >>> .el-table td,
.tech-table >>> .el-table th.is-leaf {
	border-bottom: 1px solid rgba(0, 240, 255, 0.1) !important;
}

.tech-table >>> .el-table td {
	color: #b8c5d6 !important;
	transition: all 0.3s ease;
	position: relative;
	z-index: 1;
}

.tech-table >>> .el-table__body tr {
	background: rgba(10, 14, 39, 0.3) !important;
	transition: all 0.3s ease;
	border-left: 3px solid transparent;
}

.tech-table >>> .el-table__body tr:hover {
	background: linear-gradient(90deg,
		rgba(0, 240, 255, 0.2) 0%,
		rgba(0, 240, 255, 0.15) 50%,
		rgba(0, 240, 255, 0.05) 100%) !important;
	border-left-color: #00f0ff;
}

.tech-table >>> .el-table__body tr:hover td {
	color: #e0e6ed !important;
}

.tech-table >>> .el-table__body-wrapper {
	scrollbar-width: thin;
	scrollbar-color: rgba(0, 240, 255, 0.3) rgba(10, 14, 39, 0.5);
}

.tech-table >>> .el-table__body-wrapper::-webkit-scrollbar {
	width: 8px;
	height: 8px;
}

.tech-table >>> .el-table__body-wrapper::-webkit-scrollbar-track {
	background: rgba(10, 14, 39, 0.5);
	border-radius: 4px;
}

.tech-table >>> .el-table__body-wrapper::-webkit-scrollbar-thumb {
	background: rgba(0, 240, 255, 0.3);
	border-radius: 4px;
	transition: background 0.3s;
}

.tech-table >>> .el-table__body-wrapper::-webkit-scrollbar-thumb:hover {
	background: rgba(0, 240, 255, 0.5);
}

/* ==================== 序号列拖拽样式 ==================== */
.index-with-drag {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
}

.drag-handle {
	color: rgba(0, 240, 255, 0.3);
	font-size: 14px;
	font-weight: bold;
	letter-spacing: -2px;
	transition: all 0.3s ease;
	cursor: move;
}

.tech-table >>> .el-table__row:hover .drag-handle {
	color: rgba(0, 240, 255, 0.8);
	text-shadow: 0 0 8px rgba(0, 240, 255, 0.6);
}

/* ==================== Banner 图片样式 ==================== */
.banner-image {
	width: 200px !important;
	height: 80px !important;
	border-radius: 6px;
	border: 2px solid rgba(0, 240, 255, 0.3);
	cursor: pointer;
	transition: all 0.3s ease;
	object-fit: cover;
}

.banner-image:hover {
	border-color: #00f0ff;
	transform: scale(1.05);
	box-shadow: 0 0 15px rgba(0, 240, 255, 0.5);
}

.no-image-text {
	color: #7f8ea3;
	font-size: 12px;
}

/* ==================== 价格标签 ==================== */
.price-tag {
	color: #00ff88;
	font-weight: 600;
	font-size: 13px;
	text-shadow: 0 0 8px rgba(0, 255, 136, 0.4);
}

/* ==================== 预览图片小 ==================== */
.preview-image-small {
	width: 40px !important;
	height: 40px !important;
	border-radius: 4px;
	border: 1px solid rgba(0, 240, 255, 0.3);
	cursor: pointer;
	transition: all 0.3s ease;
}

.preview-image-small:hover {
	border-color: #00f0ff;
	transform: scale(1.1);
}

/* ==================== 操作按钮 ==================== */
.action-button {
	color: #00f0ff !important;
	font-weight: 600 !important;
	padding: 4px 8px !important;
	transition: all 0.3s ease !important;
	position: relative;
	background: transparent !important;
	border-radius: 4px;
	font-size: 13px !important;
}

.action-button:hover {
	background: rgba(0, 240, 255, 0.1) !important;
}

.delete-button:hover {
	color: #ff4757 !important;
	background: rgba(255, 71, 87, 0.1) !important;
}

/* ==================== 拖拽排序样式 ==================== */
.tech-table >>> .el-table__row {
	cursor: move;
	user-select: none;
}

.tech-table >>> .sortable-ghost {
	opacity: 0.5;
	background: rgba(0, 240, 255, 0.2) !important;
	border-left: 3px solid #00f0ff !important;
}

.tech-table >>> .sortable-chosen {
	background: rgba(0, 240, 255, 0.15) !important;
	border-left: 3px solid #00f0ff !important;
	box-shadow: 0 0 20px rgba(0, 240, 255, 0.5);
}

.tech-table >>> .sortable-drag {
	background: rgba(0, 240, 255, 0.3) !important;
	border-left: 3px solid #00f0ff !important;
	box-shadow: 0 8px 32px rgba(0, 240, 255, 0.6);
	transform: rotate(2deg);
	opacity: 0.8;
}

/* ==================== 固定列样式 ==================== */
.tech-table >>> .el-table__fixed,
.tech-table >>> .el-table__fixed-right {
	background: rgba(10, 14, 39, 0.95) !important;
	box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
}

.tech-table >>> .el-table__fixed-right::before,
.tech-table >>> .el-table__fixed::before {
	background: transparent !important;
}

/* ==================== 弹窗样式 ==================== */
.tech-dialog >>> .el-dialog {
	background: rgba(26, 31, 58, 0.95) !important;
	backdrop-filter: blur(20px);
	border: 1px solid rgba(0, 240, 255, 0.3);
	box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
}

.tech-dialog >>> .el-dialog__header {
	background: linear-gradient(135deg, rgba(0, 240, 255, 0.2) 0%, rgba(0, 153, 204, 0.2) 100%);
	border-bottom: 1px solid rgba(0, 240, 255, 0.2);
	padding: 20px;
}

.tech-dialog >>> .el-dialog__title {
	color: #00f0ff !important;
	font-size: 18px;
	font-weight: 600;
	text-shadow: 0 0 10px rgba(0, 240, 255, 0.5);
}

.tech-dialog >>> .el-dialog__headerbtn {
	top: 20px;
}

.tech-dialog >>> .el-dialog__close {
	color: #00f0ff !important;
	font-size: 20px;
}

.tech-dialog >>> .el-dialog__close:hover {
	color: #ffffff !important;
}

.tech-dialog >>> .el-dialog__body {
	padding: 24px;
	max-height: 70vh;
	overflow-y: auto;
	background: transparent;
}

.tech-dialog >>> .el-dialog__footer {
	padding: 16px 24px;
	border-top: 1px solid rgba(0, 240, 255, 0.2);
	background: transparent;
}

.dialog-content {
	color: #e0e6ed;
}

/* ==================== 上传区域 ==================== */
.upload-section {
	margin-bottom: 24px;
}

.section-label {
	color: #b8c5d6;
	font-size: 14px;
	margin-bottom: 12px;
	font-weight: 500;
}

.image-preview {
	display: flex;
	align-items: center;
	gap: 16px;
}

.preview-img {
	width: 300px !important;
	height: 200px !important;
	border-radius: 8px;
	border: 2px solid rgba(0, 240, 255, 0.3);
	object-fit: cover;
}

.image-actions {
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.upload-placeholder {
	width: 300px;
	height: 200px;
	border: 2px dashed rgba(0, 240, 255, 0.3);
	border-radius: 8px;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	transition: all 0.3s ease;
	background: rgba(10, 14, 39, 0.3);
}

.upload-placeholder:hover {
	border-color: rgba(0, 240, 255, 0.6);
	background: rgba(10, 14, 39, 0.5);
}

.upload-placeholder i {
	font-size: 48px;
	color: rgba(0, 240, 255, 0.5);
	margin-bottom: 12px;
}

.upload-placeholder text {
	color: #7f8ea3;
	font-size: 14px;
}

/* ==================== 表单样式 ==================== */
.tech-form {
	margin-top: 24px;
}

.tech-form >>> .el-form-item__label {
	color: #b8c5d6 !important;
}

.tech-form >>> .el-input__inner,
.tech-form >>> .el-textarea__inner {
	background: rgba(10, 14, 39, 0.6) !important;
	border: 1px solid rgba(0, 240, 255, 0.3) !important;
	color: #e0e6ed !important;
	border-radius: 6px;
	transition: all 0.3s ease;
}

.tech-form >>> .el-input__inner:hover,
.tech-form >>> .el-textarea__inner:hover {
	border-color: rgba(0, 240, 255, 0.5) !important;
}

.tech-form >>> .el-input__inner:focus,
.tech-form >>> .el-textarea__inner:focus {
	border-color: #00f0ff !important;
	box-shadow: 0 0 20px rgba(0, 240, 255, 0.4);
	background: rgba(10, 14, 39, 0.8) !important;
}

.tech-form >>> .el-input__inner::placeholder,
.tech-form >>> .el-textarea__inner::placeholder {
	color: #4a5568 !important;
}

.tech-form >>> .el-input__count {
	background: transparent;
	color: #7f8ea3;
}

.tech-form >>> .el-input__suffix {
	color: #7f8ea3;
}

.dialog-footer {
	display: flex;
	justify-content: flex-end;
	gap: 12px;
}

/* ==================== 对话框搜索 ==================== */
.dialog-search {
	margin-bottom: 16px;
}

.dialog-search >>> .el-input__inner {
	background: rgba(10, 14, 39, 0.6) !important;
	border: 1px solid rgba(0, 240, 255, 0.3) !important;
	color: #e0e6ed !important;
	border-radius: 6px;
}

/* ==================== 分页器 ==================== */
.pagination-wrapper {
	display: flex;
	justify-content: flex-end;
	padding: 16px 0 0 0;
	margin-top: 12px;
	border-top: 1px solid rgba(0, 240, 255, 0.1);
}

.pagination-wrapper >>> .el-pagination {
	display: flex;
	align-items: center;
	gap: 8px;
}

.pagination-wrapper >>> .el-pagination.is-background .btn-next,
.pagination-wrapper >>> .el-pagination.is-background .btn-prev,
.pagination-wrapper >>> .el-pagination.is-background .el-pager li {
	background: rgba(10, 14, 39, 0.6) !important;
	color: #b8c5d6 !important;
	border: 1px solid rgba(0, 240, 255, 0.3) !important;
	border-radius: 6px;
	margin: 0 2px;
	transition: all 0.3s ease;
}

.pagination-wrapper >>> .el-pagination.is-background .el-pager li:hover,
.pagination-wrapper >>> .el-pagination.is-background .btn-next:hover,
.pagination-wrapper >>> .el-pagination.is-background .btn-prev:hover {
	color: #00f0ff !important;
	border-color: rgba(0, 240, 255, 0.5) !important;
}

.pagination-wrapper >>> .el-pagination.is-background .el-pager li.active {
	background: linear-gradient(135deg, rgba(0, 240, 255, 0.3) 0%, rgba(0, 153, 204, 0.3) 100%) !important;
	color: #00f0ff !important;
	border-color: #00f0ff !important;
	box-shadow: 0 0 20px rgba(0, 240, 255, 0.4);
	font-weight: 600;
}

.pagination-wrapper >>> .el-pagination__total,
.pagination-wrapper >>> .el-pagination__jump {
	color: #b8c5d6 !important;
}

.pagination-wrapper >>> .el-pagination__sizes .el-input .el-input__inner {
	background: rgba(10, 14, 39, 0.6) !important;
	border: 1px solid rgba(0, 240, 255, 0.3) !important;
	color: #e0e6ed !important;
	border-radius: 6px;
}

.pagination-wrapper >>> .el-input__inner {
	background: rgba(10, 14, 39, 0.6) !important;
	border: 1px solid rgba(0, 240, 255, 0.3) !important;
	color: #e0e6ed !important;
	border-radius: 6px;
}

/* ==================== 裁剪弹窗 ==================== */
.cropper-content {
	height: 500px;
	background: rgba(10, 14, 39, 0.5);
	border-radius: 8px;
	overflow: hidden;
}

/* ==================== Loading 样式 ==================== */
.tech-table >>> .el-loading-mask {
	background-color: rgba(10, 14, 39, 0.8) !important;
}

.tech-table >>> .el-loading-spinner .circular {
	stroke: #00f0ff !important;
}

.tech-table >>> .el-loading-spinner .el-loading-text {
	color: #00f0ff !important;
}

/* ==================== 开关样式 ==================== */
.status-switch >>> .el-switch__core {
	background: rgba(74, 85, 104, 0.6) !important;
	border: 1px solid rgba(74, 85, 104, 0.5) !important;
	width: 40px !important;
	height: 20px !important;
}

.status-switch >>> .el-switch__core::after {
	width: 16px !important;
	height: 16px !important;
	top: 1px !important;
}

.status-switch.is-checked >>> .el-switch__core {
	background: linear-gradient(135deg, #00f0ff 0%, #0099cc 100%) !important;
	border-color: #00f0ff !important;
	box-shadow: 0 0 15px rgba(0, 240, 255, 0.4);
}

.tech-switch >>> .el-switch__core {
	background: rgba(10, 14, 39, 0.6) !important;
	border: 1px solid rgba(0, 240, 255, 0.3) !important;
	height: 22px;
	transition: all 0.3s ease;
}

.tech-switch >>> .el-switch__core::after {
	background: #7f8ea3;
	width: 16px;
	height: 16px;
	top: 2px;
}

.tech-switch.is-checked >>> .el-switch__core {
	background: linear-gradient(135deg, #00f0ff 0%, #0099cc 100%) !important;
	border-color: #00f0ff !important;
	box-shadow: 0 0 15px rgba(0, 240, 255, 0.4);
}

.tech-switch.is-checked >>> .el-switch__core::after {
	background: #0a0e27;
}

.tech-switch >>> .el-switch__label {
	color: #b8c5d6;
	font-size: 13px;
}

.tech-switch >>> .el-switch__label.is-active {
	color: #00f0ff;
}

/* ==================== 响应式 ==================== */
@media (max-width: 768px) {
	.page-container {
		padding: 12px;
	}

	.tech-card {
		padding: 12px;
		margin-bottom: 12px;
	}

	.filter-content {
		flex-direction: column;
	}

	.preview-img,
	.upload-placeholder {
		width: 100% !important;
	}
}
</style>